
#define _GNU_SOURCE

#include <pthread.h>
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <time.h>

#include <imp/imp_log.h>
#include <imp/imp_common.h>
#include <imp/imp_system.h>
#include <imp/imp_framesource.h>
#include <imp/imp_encoder.h>

#include "sample-common.h"

#define TAG "Sample-Encoder-changeRes-test"

#define SAVE_STREAM

extern struct chn_conf chn[];
extern int direct_switch;
extern IMPSensorInfo sensor_info;

static IMPEncoderRcMode S_RC_METHOD_TEST = ENC_RC_MODE_CBR;
pthread_t getStreamTid[3+FS_CHN_NUM];
int getVideo[] = { 0, 1, 0, 0 };
int getJpeg[] = { 1, 0, 0, 0 };
int changeWidth[] = { 704, 640, 1280, 2048, 1920, 800 };
int changeHeight[] = { 576, 360, 728, 1536, 1080, 600 };
static int totalSaveCnt = 0;
#ifdef SAVE_STREAM
static int save_stream_test(int fd, IMPEncoderStream *stream);
static int save_stream_by_name_test(char *stream_prefix, int idx, IMPEncoderStream *stream);
#endif
static void *get_video_stream_chn0(void *args);
static void *get_video_stream_chn1(void *args);
static void *get_jpeg_stream_chn3(void *args);

int main(int argc, char *argv[])
{
	int i = 0;
	int ret = 0;

	totalSaveCnt = 20;
	if(argc > 1) {
		totalSaveCnt = atoi(argv[1]);
	}

	direct_switch = 1;

	chn[0].enable = 1;
	chn[1].enable = 1;
	chn[2].enable = 0;

	/* Step.1 System init */
	{
		memset(&sensor_info, 0, sizeof(IMPSensorInfo));
		memcpy(sensor_info.name, SENSOR_NAME, sizeof(SENSOR_NAME));
		sensor_info.cbus_type = SENSOR_CUBS_TYPE;
		memcpy(sensor_info.i2c.type, SENSOR_NAME, sizeof(SENSOR_NAME));
		sensor_info.i2c.addr = SENSOR_I2C_ADDR;
		sensor_info.i2c.i2c_adapter_id = SENSOR_I2C_ADAPTER_ID;

		ret = IMP_ISP_Open();
		if (ret < 0) {
			IMP_LOG_ERR(TAG, "IMP_ISP_Open failed\n");
			return -1;
		}

		ret = IMP_ISP_AddSensor(&sensor_info);
		if (ret < 0) {
			IMP_LOG_ERR(TAG, "IMP_ISP_AddSensor failed\n");
			return -1;
		}

		ret = IMP_ISP_EnableSensor();
		if (ret < 0) {
			IMP_LOG_ERR(TAG, "IMP_ISP_EnableSensor failed\n");
			return -1;
		}

		ret = IMP_System_Init();
		if (ret < 0) {
			IMP_LOG_ERR(TAG, "IMP_System_Init failed\n");
			return -1;
		}

		ret = IMP_ISP_EnableTuning();
		if (ret < 0) {
			IMP_LOG_ERR(TAG, "IMP_ISP_EnableTuning failed\n");
			return -1;
		}

		ret = IMP_ISP_Tuning_SetSensorFPS(SENSOR_FRAME_RATE_NUM, SENSOR_FRAME_RATE_DEN);
		if (ret < 0) {
			IMP_LOG_ERR(TAG, "IMP_ISP_Tuning_SetSensorFPS failed\n");
			return -1;
		}
	}

	/* Step.2 FrameSource init */
	{
		for (i = 0; i < FS_CHN_NUM; i++) {
			if (chn[i].enable) {
				ret = IMP_FrameSource_CreateChn(chn[i].index, &chn[i].fs_chn_attr);
				if (ret < 0) {
					IMP_LOG_ERR(TAG, "IMP_FrameSource_CreateChn(%d) failed\n", chn[i].index);
					return -1;
				}

				ret = IMP_FrameSource_SetChnAttr(chn[i].index, &chn[i].fs_chn_attr);
				if (ret < 0) {
					IMP_LOG_ERR(TAG, "IMP_FrameSource_SetChnAttr(%d) failed\n", chn[i].index);
					return -1;
				}
			}
		}
	}

	/* Step.3 Encoder init */
	{
		IMPEncoderCHNAttr chnAttr;
		IMPEncoderAttr *encAttr;
		IMPEncoderRcAttr *rcAttr;
		for (i = 0; i < FS_CHN_NUM; i++) {
			if (chn[i].enable) {
				ret = IMP_Encoder_CreateGroup(chn[i].index);
				if (ret < 0) {
					IMP_LOG_ERR(TAG, "IMP_Encoder_CreateGroup(%d) failed\n", chn[i].index);
					return -1;
				}
			}
		}
		//h264
		for (i = 0; i < FS_CHN_NUM; i++) {
			if (chn[i].enable) {
				memset(&chnAttr, 0, sizeof(IMPEncoderCHNAttr));
				encAttr = &chnAttr.encAttr;
				rcAttr = &chnAttr.rcAttr;
				encAttr->enType = chn[i].payloadType;
				if ((chn[i].fs_chn_attr.picHeight > 1920) || (chn[i].fs_chn_attr.picHeight == 1920)) {
					encAttr->bufSize = chn[i].fs_chn_attr.picWidth*chn[i].fs_chn_attr.picHeight*3/10;
				} else if ((chn[i].fs_chn_attr.picHeight > 1520) || (chn[i].fs_chn_attr.picHeight == 1520)) {
					encAttr->bufSize = chn[i].fs_chn_attr.picWidth*chn[i].fs_chn_attr.picHeight*3/8;
				} else if ((chn[i].fs_chn_attr.picHeight > 1080) || (chn[i].fs_chn_attr.picHeight == 1080)) {
					encAttr->bufSize = chn[i].fs_chn_attr.picWidth*chn[i].fs_chn_attr.picHeight/2;
				} else {
					encAttr->bufSize = chn[i].fs_chn_attr.picWidth*chn[i].fs_chn_attr.picHeight*3/4;
				}
				encAttr->profile = -1;
				encAttr->picWidth = chn[i].fs_chn_attr.picWidth;
				encAttr->picHeight = chn[i].fs_chn_attr.picHeight;
				rcAttr->outFrmRate.frmRateNum = chn[i].fs_chn_attr.outFrmRateNum;
				rcAttr->outFrmRate.frmRateDen = chn[i].fs_chn_attr.outFrmRateDen;
				rcAttr->maxGop = 2 * rcAttr->outFrmRate.frmRateNum / rcAttr->outFrmRate.frmRateDen;
				if (S_RC_METHOD_TEST == ENC_RC_MODE_CBR) {
					rcAttr->attrRcMode.rcMode = ENC_RC_MODE_CBR;
					rcAttr->attrRcMode.attrH264Cbr.outBitRate = BITRATE_720P_Kbs * (chn[i].fs_chn_attr.picWidth * chn[i].fs_chn_attr.picHeight) / (1280 * 720);
					rcAttr->attrRcMode.attrH264Cbr.maxQp = 45;
					rcAttr->attrRcMode.attrH264Cbr.minQp = 15;
					rcAttr->attrRcMode.attrH264Cbr.iBiasLvl = 0;
					rcAttr->attrRcMode.attrH264Cbr.frmQPStep = 3;
					rcAttr->attrRcMode.attrH264Cbr.gopQPStep = 15;
					rcAttr->attrRcMode.attrH264Cbr.adaptiveMode = false;
					rcAttr->attrRcMode.attrH264Cbr.gopRelation = false;

					rcAttr->attrHSkip.hSkipAttr.skipType = IMP_Encoder_STYPE_N1X;
					rcAttr->attrHSkip.hSkipAttr.m = 0;
					rcAttr->attrHSkip.hSkipAttr.n = 0;
					rcAttr->attrHSkip.hSkipAttr.maxSameSceneCnt = 0;
					rcAttr->attrHSkip.hSkipAttr.bEnableScenecut = 0;
					rcAttr->attrHSkip.hSkipAttr.bBlackEnhance = 0;
					rcAttr->attrHSkip.maxHSkipType = IMP_Encoder_STYPE_N1X;
				} else if (S_RC_METHOD_TEST == ENC_RC_MODE_VBR) {
					rcAttr->attrRcMode.rcMode = ENC_RC_MODE_VBR;
					rcAttr->attrRcMode.attrH264Vbr.maxQp = 45;
					rcAttr->attrRcMode.attrH264Vbr.minQp = 15;
					rcAttr->attrRcMode.attrH264Vbr.staticTime = 2;
					rcAttr->attrRcMode.attrH264Vbr.maxBitRate = BITRATE_720P_Kbs * (chn[i].fs_chn_attr.picWidth * chn[i].fs_chn_attr.picHeight) / (1280 * 720);
					rcAttr->attrRcMode.attrH264Vbr.iBiasLvl = 0;
					rcAttr->attrRcMode.attrH264Vbr.changePos = 80;
					rcAttr->attrRcMode.attrH264Vbr.qualityLvl = 2;
					rcAttr->attrRcMode.attrH264Vbr.frmQPStep = 3;
					rcAttr->attrRcMode.attrH264Vbr.gopQPStep = 15;
					rcAttr->attrRcMode.attrH264Vbr.gopRelation = false;

					rcAttr->attrHSkip.hSkipAttr.skipType = IMP_Encoder_STYPE_N1X;
					rcAttr->attrHSkip.hSkipAttr.m = 0;
					rcAttr->attrHSkip.hSkipAttr.n = 0;
					rcAttr->attrHSkip.hSkipAttr.maxSameSceneCnt = 0;
					rcAttr->attrHSkip.hSkipAttr.bEnableScenecut = 0;
					rcAttr->attrHSkip.hSkipAttr.bBlackEnhance = 0;
					rcAttr->attrHSkip.maxHSkipType = IMP_Encoder_STYPE_N1X;
				} else if (S_RC_METHOD_TEST == ENC_RC_MODE_SMART) {
					rcAttr->attrRcMode.rcMode = ENC_RC_MODE_SMART;
					rcAttr->attrRcMode.attrH264Smart.maxQp = 45;
					rcAttr->attrRcMode.attrH264Smart.minQp = 15;
					rcAttr->attrRcMode.attrH264Smart.staticTime = 2;
					rcAttr->attrRcMode.attrH264Smart.maxBitRate = BITRATE_720P_Kbs * (chn[i].fs_chn_attr.picWidth * chn[i].fs_chn_attr.picHeight) / (1280 * 720);
					rcAttr->attrRcMode.attrH264Smart.iBiasLvl = 0;
					rcAttr->attrRcMode.attrH264Smart.changePos = 80;
					rcAttr->attrRcMode.attrH264Smart.qualityLvl = 2;
					rcAttr->attrRcMode.attrH264Smart.frmQPStep = 3;
					rcAttr->attrRcMode.attrH264Smart.gopQPStep = 15;
					rcAttr->attrRcMode.attrH264Smart.gopRelation = false;

					rcAttr->attrHSkip.hSkipAttr.skipType = IMP_Encoder_STYPE_N1X;
					rcAttr->attrHSkip.hSkipAttr.m = rcAttr->maxGop - 1;
					rcAttr->attrHSkip.hSkipAttr.n = 1;
					rcAttr->attrHSkip.hSkipAttr.maxSameSceneCnt = 6;
					rcAttr->attrHSkip.hSkipAttr.bEnableScenecut = 0;
					rcAttr->attrHSkip.hSkipAttr.bBlackEnhance = 0;
					rcAttr->attrHSkip.maxHSkipType = IMP_Encoder_STYPE_N1X;
				} else {
					rcAttr->attrRcMode.rcMode = ENC_RC_MODE_FIXQP;
					rcAttr->attrRcMode.attrH264FixQp.qp = 35;

					rcAttr->attrHSkip.hSkipAttr.skipType = IMP_Encoder_STYPE_N1X;
					rcAttr->attrHSkip.hSkipAttr.m = 0;
					rcAttr->attrHSkip.hSkipAttr.n = 0;
					rcAttr->attrHSkip.hSkipAttr.maxSameSceneCnt = 0;
					rcAttr->attrHSkip.hSkipAttr.bEnableScenecut = 0;
					rcAttr->attrHSkip.hSkipAttr.bBlackEnhance = 0;
					rcAttr->attrHSkip.maxHSkipType = IMP_Encoder_STYPE_N1X;
				}

				if (direct_switch == 1) {
					if (0 == chn[i].index) chnAttr.bEnableIvdc = true;
				}

				ret = IMP_Encoder_CreateChn(chn[i].index, &chnAttr);
				if (ret < 0) {
					IMP_LOG_ERR(TAG, "IMP_Encoder_CreateChn(%d) failed\n", chn[i].index);
					return -1;
				}
			}
		}
		//jpeg
		for (i = 0; i <  FS_CHN_NUM; i++) {
			if (chn[i].enable && (chn[i].index == 0)) {
				memset(&chnAttr, 0, sizeof(IMPEncoderCHNAttr));
				encAttr = &chnAttr.encAttr;

				encAttr->enType = PT_JPEG;
				encAttr->bufSize = 0;
				encAttr->profile = 0;
				encAttr->picWidth = chn[i].fs_chn_attr.picWidth;
				encAttr->picHeight = chn[i].fs_chn_attr.picHeight;

				if (direct_switch == 1) {
					if (0 == chn[i].index) chnAttr.bEnableIvdc = true;
				}

				ret = IMP_Encoder_CreateChn(3+chn[i].index, &chnAttr);
				if (ret < 0) {
					IMP_LOG_ERR(TAG, "IMP_Encoder_CreateChn(%d) failed\n", 3+chn[i].index);
					return -1;
				}
			}
		}
		for (i = 0; i < FS_CHN_NUM; i++) {
			if (chn[i].enable) {
				ret = IMP_Encoder_RegisterChn(chn[i].index, chn[i].index);
				if (ret < 0) {
					IMP_LOG_ERR(TAG, "IMP_Encoder_RegisterChn(%d, %d) failed\n", chn[i].index, chn[i].index);
					return -1;
				}
				if (chn[i].index == 0) {
					ret = IMP_Encoder_RegisterChn(chn[i].index, 3+chn[i].index);
					if (ret < 0) {
						IMP_LOG_ERR(TAG, "IMP_Encoder_RegisterChn(%d, %d) failed\n", chn[i].index, 3+chn[i].index);
						return -1;
					}
				}
			}
		}
	}

	/* Step.4 Bind */
	{
		for (i = 0; i < FS_CHN_NUM; i++) {
			if (chn[i].enable) {
				ret = IMP_System_Bind(&chn[i].framesource_chn, &chn[i].imp_encoder);
				if (ret < 0) {
					IMP_LOG_ERR(TAG, "IMP_System_Bind framesourc%d and encoder%d failed\n", chn[i].framesource_chn.groupID, chn[i].imp_encoder.groupID);
					return -1;
				}
			}
		}
	}

	/* Step.5 Stream On */
	{
		for (i = 0; i < FS_CHN_NUM; i++) {
			if (chn[i].enable) {
				ret = IMP_FrameSource_EnableChn(chn[i].index);
				if (ret < 0) {
					IMP_LOG_ERR(TAG, "IMP_FrameSource_EnableChn(%d) failed\n", chn[i].index);
					return -1;
				}
			}
		}
	}

	/* Step.6 Get stream and Snap */
	{
		for (i = 0; i < FS_CHN_NUM; i++) {
			if (chn[i].enable && (chn[i].index == 0)) {
				int arg = (chn[i].payloadType << 16 | chn[i].index);
				ret = pthread_create(&getStreamTid[chn[i].index], NULL, get_video_stream_chn0, (void *)arg);
				if (ret < 0) {
					IMP_LOG_ERR(TAG, "Create Chn%d get_video_stream failed\n", chn[i].index);
					return -1;
				}
				arg = (PT_JPEG << 16 | (3+chn[i].index));
				ret = pthread_create(&getStreamTid[3+chn[i].index], NULL, get_jpeg_stream_chn3, (void *)arg);
				if (ret < 0) {
					IMP_LOG_ERR(TAG, "Create Chn%d get_jpeg_stream failed\n", 3+chn[i].index);
					return -1;
				}
			} else if (chn[i].enable && (chn[i].index == 1)) {
				int arg = (chn[i].payloadType << 16 | chn[i].index);
				ret = pthread_create(&getStreamTid[chn[i].index], NULL, get_video_stream_chn1, (void *)arg);
				if (ret < 0) {
					IMP_LOG_ERR(TAG, "Create Chn%d get_video_stream failed\n", chn[i].index);
					return -1;
				}
			}
		}
	}

	{
		int j = 0;
		int resCnt = (sizeof(changeWidth) > sizeof(changeHeight) ? sizeof(changeHeight) : sizeof(changeWidth)) / sizeof(int);
		int changeCnt = resCnt * totalSaveCnt;
		for (j = 0; j < changeCnt; j++) {
			for (i = 0; i < FS_CHN_NUM; i++) {
				if (chn[i].enable && (chn[i].index == 0)) {
					pthread_join(getStreamTid[chn[i].index], NULL);
					pthread_join(getStreamTid[3+chn[i].index], NULL);
				}
			}

			for (i = 0; i < FS_CHN_NUM; i++) {
				if (chn[i].enable && (chn[i].index == 0)) {
					ret = IMP_FrameSource_DisableChn(chn[i].index);
					if (ret < 0) {
						IMP_LOG_ERR(TAG, "IMP_FrameSource_DisableChn(%d) failed\n", chn[i].index);
						return -1;
					}
				}
			}

			for (i = 0; i < FS_CHN_NUM; i++) {
				if (chn[i].enable && (chn[i].index == 0)) {
					ret = IMP_System_UnBind(&chn[i].framesource_chn, &chn[i].imp_encoder);
					if (ret < 0) {
						IMP_LOG_ERR(TAG, "IMP_System_UnBind framesource%d and encoder%d failed\n", chn[i].framesource_chn.groupID, chn[i].imp_encoder.groupID);
						return -1;
					}
				}
			}

			IMPEncoderCHNStat chnStat;
			for (i = 0; i < FS_CHN_NUM; i++) {
				if (chn[i].enable && (chn[i].index == 0)) {
					memset(&chnStat, 0, sizeof(IMPEncoderCHNStat));
					ret = IMP_Encoder_Query(chn[i].index, &chnStat);
					if (ret < 0) {
						IMP_LOG_ERR(TAG, "IMP_Encoder_Query(%d) failed\n", chn[i].index);
						return -1;
					}

					if (chnStat.registered) {
						ret = IMP_Encoder_UnRegisterChn(chn[i].index);
						if (ret < 0) {
							IMP_LOG_ERR(TAG, "IMP_Encoder_UnRegisterChn(%d) failed\n", chn[i].index);
							return -1;
						}

						ret = IMP_Encoder_DestroyChn(chn[i].index);
						if (ret < 0) {
							IMP_LOG_ERR(TAG, "IMP_Encoder_DestroyChn(%d) failed\n", chn[i].index);
							return -1;
						}
					}
					memset(&chnStat, 0, sizeof(IMPEncoderCHNStat));
					ret = IMP_Encoder_Query(3+chn[i].index, &chnStat);
					if (ret < 0) {
						IMP_LOG_ERR(TAG, "IMP_Encoder_Query(%d) failed\n", 3+chn[i].index);
						return -1;
					}

					if (chnStat.registered) {
						ret = IMP_Encoder_UnRegisterChn(3+chn[i].index);
						if (ret < 0) {
							IMP_LOG_ERR(TAG, "IMP_Encoder_UnRegisterChn(%d) failed\n", 3+chn[i].index);
							return -1;
						}

						ret = IMP_Encoder_DestroyChn(3+chn[i].index);
						if (ret < 0) {
							IMP_LOG_ERR(TAG, "IMP_Encoder_DestroyChn(%d) failed\n", 3+chn[i].index);
							return -1;
						}
					}
				}
			}
			for (i = 0; i < FS_CHN_NUM; i++) {
				if (chn[i].enable && (chn[i].index == 0)) {
					ret = IMP_Encoder_DestroyGroup(chn[i].index);
					if (ret < 0) {
						IMP_LOG_ERR(TAG, "IMP_Encoder_DestroyGroup(%d) failed\n", chn[i].index);
						return -1;
					}
				}
			}

			for (i = 0; i < FS_CHN_NUM; i++) {
				if (chn[i].enable && (chn[i].index == 0)) {
					if ((changeWidth[j%resCnt] == SENSOR_WIDTH) && (changeHeight[j%resCnt] == SENSOR_HEIGHT))
						chn[i].fs_chn_attr.scaler.enable = 0;
					else
						chn[i].fs_chn_attr.scaler.enable = 1;
					chn[i].fs_chn_attr.scaler.outwidth = changeWidth[j%resCnt];
					chn[i].fs_chn_attr.scaler.outheight = changeHeight[j%resCnt];
					chn[i].fs_chn_attr.crop.enable = 0;
					chn[i].fs_chn_attr.crop.top = 0;
					chn[i].fs_chn_attr.crop.left = 0;
					chn[i].fs_chn_attr.crop.width = changeWidth[j%resCnt];
					chn[i].fs_chn_attr.crop.height = changeHeight[j%resCnt];
					chn[i].fs_chn_attr.picWidth = changeWidth[j%resCnt];
					chn[i].fs_chn_attr.picHeight = changeHeight[j%resCnt];

					ret = IMP_FrameSource_SetChnAttr(chn[i].index, &chn[i].fs_chn_attr);
					if (ret < 0) {
						IMP_LOG_ERR(TAG, "IMP_FrameSource_SetChnAttr(%d) failed\n", chn[i].index);
						return -1;
					}
				}
			}

			IMPEncoderCHNAttr chnAttr;
			IMPEncoderAttr *encAttr;
			IMPEncoderRcAttr *rcAttr;
			for (i = 0; i < FS_CHN_NUM; i++) {
				if (chn[i].enable && (chn[i].index == 0)) {
					ret = IMP_Encoder_CreateGroup(chn[i].index);
					if (ret < 0) {
						IMP_LOG_ERR(TAG, "IMP_Encoder_CreateGroup(%d) failed\n", chn[i].index);
						return -1;
					}
				}
			}
			//h264
			for (i = 0; i < FS_CHN_NUM; i++) {
				if (chn[i].enable && (chn[i].index == 0)) {
					memset(&chnAttr, 0, sizeof(IMPEncoderCHNAttr));
					encAttr = &chnAttr.encAttr;
					rcAttr = &chnAttr.rcAttr;
					encAttr->enType = chn[i].payloadType;
					if ((chn[i].fs_chn_attr.picHeight > 1920) || (chn[i].fs_chn_attr.picHeight == 1920)) {
						encAttr->bufSize = chn[i].fs_chn_attr.picWidth*chn[i].fs_chn_attr.picHeight*3/10;
					} else if ((chn[i].fs_chn_attr.picHeight > 1520) || (chn[i].fs_chn_attr.picHeight == 1520)) {
						encAttr->bufSize = chn[i].fs_chn_attr.picWidth*chn[i].fs_chn_attr.picHeight*3/8;
					} else if ((chn[i].fs_chn_attr.picHeight > 1080) || (chn[i].fs_chn_attr.picHeight == 1080)) {
						encAttr->bufSize = chn[i].fs_chn_attr.picWidth*chn[i].fs_chn_attr.picHeight/2;
					} else {
						encAttr->bufSize = chn[i].fs_chn_attr.picWidth*chn[i].fs_chn_attr.picHeight*3/4;
					}
					encAttr->profile = -1;
					encAttr->picWidth = chn[i].fs_chn_attr.picWidth;
					encAttr->picHeight = chn[i].fs_chn_attr.picHeight;
					rcAttr->outFrmRate.frmRateNum = chn[i].fs_chn_attr.outFrmRateNum;
					rcAttr->outFrmRate.frmRateDen = chn[i].fs_chn_attr.outFrmRateDen;
					rcAttr->maxGop = 2 * rcAttr->outFrmRate.frmRateNum / rcAttr->outFrmRate.frmRateDen;
					if (S_RC_METHOD_TEST == ENC_RC_MODE_CBR) {
						rcAttr->attrRcMode.rcMode = ENC_RC_MODE_CBR;
						rcAttr->attrRcMode.attrH264Cbr.outBitRate = BITRATE_720P_Kbs * (chn[i].fs_chn_attr.picWidth * chn[i].fs_chn_attr.picHeight) / (1280 * 720);
						rcAttr->attrRcMode.attrH264Cbr.maxQp = 45;
						rcAttr->attrRcMode.attrH264Cbr.minQp = 15;
						rcAttr->attrRcMode.attrH264Cbr.iBiasLvl = 0;
						rcAttr->attrRcMode.attrH264Cbr.frmQPStep = 3;
						rcAttr->attrRcMode.attrH264Cbr.gopQPStep = 15;
						rcAttr->attrRcMode.attrH264Cbr.adaptiveMode = false;
						rcAttr->attrRcMode.attrH264Cbr.gopRelation = false;

						rcAttr->attrHSkip.hSkipAttr.skipType = IMP_Encoder_STYPE_N1X;
						rcAttr->attrHSkip.hSkipAttr.m = 0;
						rcAttr->attrHSkip.hSkipAttr.n = 0;
						rcAttr->attrHSkip.hSkipAttr.maxSameSceneCnt = 0;
						rcAttr->attrHSkip.hSkipAttr.bEnableScenecut = 0;
						rcAttr->attrHSkip.hSkipAttr.bBlackEnhance = 0;
						rcAttr->attrHSkip.maxHSkipType = IMP_Encoder_STYPE_N1X;
					} else if (S_RC_METHOD_TEST == ENC_RC_MODE_VBR) {
						rcAttr->attrRcMode.rcMode = ENC_RC_MODE_VBR;
						rcAttr->attrRcMode.attrH264Vbr.maxQp = 45;
						rcAttr->attrRcMode.attrH264Vbr.minQp = 15;
						rcAttr->attrRcMode.attrH264Vbr.staticTime = 2;
						rcAttr->attrRcMode.attrH264Vbr.maxBitRate = BITRATE_720P_Kbs * (chn[i].fs_chn_attr.picWidth * chn[i].fs_chn_attr.picHeight) / (1280 * 720);
						rcAttr->attrRcMode.attrH264Vbr.iBiasLvl = 0;
						rcAttr->attrRcMode.attrH264Vbr.changePos = 80;
						rcAttr->attrRcMode.attrH264Vbr.qualityLvl = 2;
						rcAttr->attrRcMode.attrH264Vbr.frmQPStep = 3;
						rcAttr->attrRcMode.attrH264Vbr.gopQPStep = 15;
						rcAttr->attrRcMode.attrH264Vbr.gopRelation = false;

						rcAttr->attrHSkip.hSkipAttr.skipType = IMP_Encoder_STYPE_N1X;
						rcAttr->attrHSkip.hSkipAttr.m = 0;
						rcAttr->attrHSkip.hSkipAttr.n = 0;
						rcAttr->attrHSkip.hSkipAttr.maxSameSceneCnt = 0;
						rcAttr->attrHSkip.hSkipAttr.bEnableScenecut = 0;
						rcAttr->attrHSkip.hSkipAttr.bBlackEnhance = 0;
						rcAttr->attrHSkip.maxHSkipType = IMP_Encoder_STYPE_N1X;
					} else if (S_RC_METHOD_TEST == ENC_RC_MODE_SMART) {
						rcAttr->attrRcMode.rcMode = ENC_RC_MODE_SMART;
						rcAttr->attrRcMode.attrH264Smart.maxQp = 45;
						rcAttr->attrRcMode.attrH264Smart.minQp = 15;
						rcAttr->attrRcMode.attrH264Smart.staticTime = 2;
						rcAttr->attrRcMode.attrH264Smart.maxBitRate = BITRATE_720P_Kbs * (chn[i].fs_chn_attr.picWidth * chn[i].fs_chn_attr.picHeight) / (1280 * 720);
						rcAttr->attrRcMode.attrH264Smart.iBiasLvl = 0;
						rcAttr->attrRcMode.attrH264Smart.changePos = 80;
						rcAttr->attrRcMode.attrH264Smart.qualityLvl = 2;
						rcAttr->attrRcMode.attrH264Smart.frmQPStep = 3;
						rcAttr->attrRcMode.attrH264Smart.gopQPStep = 15;
						rcAttr->attrRcMode.attrH264Smart.gopRelation = false;

						rcAttr->attrHSkip.hSkipAttr.skipType = IMP_Encoder_STYPE_N1X;
						rcAttr->attrHSkip.hSkipAttr.m = rcAttr->maxGop - 1;
						rcAttr->attrHSkip.hSkipAttr.n = 1;
						rcAttr->attrHSkip.hSkipAttr.maxSameSceneCnt = 6;
						rcAttr->attrHSkip.hSkipAttr.bEnableScenecut = 0;
						rcAttr->attrHSkip.hSkipAttr.bBlackEnhance = 0;
						rcAttr->attrHSkip.maxHSkipType = IMP_Encoder_STYPE_N1X;
					} else {
						rcAttr->attrRcMode.rcMode = ENC_RC_MODE_FIXQP;
						rcAttr->attrRcMode.attrH264FixQp.qp = 35;

						rcAttr->attrHSkip.hSkipAttr.skipType = IMP_Encoder_STYPE_N1X;
						rcAttr->attrHSkip.hSkipAttr.m = 0;
						rcAttr->attrHSkip.hSkipAttr.n = 0;
						rcAttr->attrHSkip.hSkipAttr.maxSameSceneCnt = 0;
						rcAttr->attrHSkip.hSkipAttr.bEnableScenecut = 0;
						rcAttr->attrHSkip.hSkipAttr.bBlackEnhance = 0;
						rcAttr->attrHSkip.maxHSkipType = IMP_Encoder_STYPE_N1X;
					}

					if (direct_switch == 1) {
						if (0 == chn[i].index) chnAttr.bEnableIvdc = true;
					}

					ret = IMP_Encoder_CreateChn(chn[i].index, &chnAttr);
					if (ret < 0) {
						IMP_LOG_ERR(TAG, "IMP_Encoder_CreateChn(%d) failed\n", chn[i].index);
						return -1;
					}
				}
			}
			//jpeg
			for (i = 0; i <  FS_CHN_NUM; i++) {
				if (chn[i].enable && (chn[i].index == 0)) {
					memset(&chnAttr, 0, sizeof(IMPEncoderCHNAttr));
					encAttr = &chnAttr.encAttr;

					encAttr->enType = PT_JPEG;
					encAttr->bufSize = 0;
					encAttr->profile = 0;
					encAttr->picWidth = chn[i].fs_chn_attr.picWidth;
					encAttr->picHeight = chn[i].fs_chn_attr.picHeight;

					if (direct_switch == 1) {
						if (0 == chn[i].index) chnAttr.bEnableIvdc = true;
					}

					ret = IMP_Encoder_CreateChn(3+chn[i].index, &chnAttr);
					if (ret < 0) {
						IMP_LOG_ERR(TAG, "IMP_Encoder_CreateChn(%d) failed\n", 3+chn[i].index);
						return -1;
					}
				}
			}
			for (i = 0; i < FS_CHN_NUM; i++) {
				if (chn[i].enable && (chn[i].index == 0)) {
					ret = IMP_Encoder_RegisterChn(chn[i].index, chn[i].index);
					if (ret < 0) {
						IMP_LOG_ERR(TAG, "IMP_Encoder_RegisterChn(%d, %d) failed\n", chn[i].index, chn[i].index);
						return -1;
					}
					ret = IMP_Encoder_RegisterChn(chn[i].index, 3+chn[i].index);
					if (ret < 0) {
						IMP_LOG_ERR(TAG, "IMP_Encoder_RegisterChn(%d, %d) failed\n", chn[i].index, 3+chn[i].index);
						return -1;
					}
				}
			}

			for (i = 0; i < FS_CHN_NUM; i++) {
				if (chn[i].enable && (chn[i].index == 0)) {
					ret = IMP_System_Bind(&chn[i].framesource_chn, &chn[i].imp_encoder);
					if (ret < 0) {
						IMP_LOG_ERR(TAG, "IMP_System_Bind framesourc%d and encoder%d failed\n", chn[i].framesource_chn.groupID, chn[i].imp_encoder.groupID);
						return -1;
					}
				}
			}

			for (i = 0; i < FS_CHN_NUM; i++) {
				if (chn[i].enable && (chn[i].index == 0)) {
					ret = IMP_FrameSource_EnableChn(chn[i].index);
					if (ret < 0) {
						IMP_LOG_ERR(TAG, "IMP_FrameSource_EnableChn(%d) failed\n", chn[i].index);
						return -1;
					}
				}
			}

			getJpeg[0] = 1;
			for (i = 0; i < FS_CHN_NUM; i++) {
				if (chn[i].enable && (chn[i].index == 0)) {
					int arg = (chn[i].payloadType << 16 | chn[i].index);
					ret = pthread_create(&getStreamTid[chn[i].index], NULL, get_video_stream_chn0, (void *)arg);
					if (ret < 0) {
						IMP_LOG_ERR(TAG, "Create Chn%d get_video_stream failed\n", chn[i].index);
						return -1;
					}
					arg = (PT_JPEG << 16 | (3+chn[i].index));
					ret = pthread_create(&getStreamTid[3+chn[i].index], NULL, get_jpeg_stream_chn3, (void *)arg);
					if (ret < 0) {
						IMP_LOG_ERR(TAG, "Create Chn%d get_jpeg_stream failed\n", 3+chn[i].index);
						return -1;
					}
				}
			}
			int chnNum = 0;
			IMPFSChnAttr tmpchnAttr;
			ret = IMP_FrameSource_GetChnAttr(chnNum, &tmpchnAttr);
			if (ret < 0) {
				IMP_LOG_ERR(TAG, "Chn%d GetChnAttr failed\n", chnNum);
				return -1;
			}
			if(tmpchnAttr.picWidth == changeWidth[j%resCnt] && tmpchnAttr.picHeight == changeHeight[j%resCnt])
				printf("\033[1;31m change count = %d \033[0m\n", j);
			else {
				int stream_fd = -1;
				stream_fd = open("/tmp/log.txt", O_RDWR | O_CREAT | O_APPEND, 0644);
				if (stream_fd < 0) {
					IMP_LOG_ERR(TAG, "failed open fd!\n");
					return -1;
				}
				char error[128];
				sprintf(error, "chn %d_Encoder Change Res error!!!\n", chnNum);
				ret = write(stream_fd, error, 34);
				if (ret == -1) {
					IMP_LOG_ERR(TAG, "failed write! \n");
					return -1;
				}
				close(stream_fd);
			}
		}
		getVideo[1] = 0;
	}

	{
		for (i = 0; i < FS_CHN_NUM; i++) {
			if (chn[i].enable) {
				pthread_join(getStreamTid[chn[i].index], NULL);
				if (chn[i].index == 0)
					pthread_join(getStreamTid[3+chn[i].index], NULL);
			}
		}
	}

	/* Step.a Stream Off */
	{
		for (i = 0; i < FS_CHN_NUM; i++) {
			if (chn[i].enable) {
				ret = IMP_FrameSource_DisableChn(chn[i].index);
				if (ret < 0) {
					IMP_LOG_ERR(TAG, "IMP_FrameSource_DisableChn(%d) failed\n", chn[i].index);
					return -1;
				}
			}
		}
	}

	/* Step.b UnBind */
	{
		for (i = 0; i < FS_CHN_NUM; i++) {
			if (chn[i].enable) {
				ret = IMP_System_UnBind(&chn[i].framesource_chn, &chn[i].imp_encoder);
				if (ret < 0) {
					IMP_LOG_ERR(TAG, "IMP_System_UnBind framesource%d and encoder%d failed\n", chn[i].framesource_chn.groupID, chn[i].imp_encoder.groupID);
					return -1;
				}
			}
		}
	}

	/* Step.c Encoder exit */
	{
		IMPEncoderCHNStat chnStat;
		for (i = 0; i < FS_CHN_NUM; i++) {
			if (chn[i].enable) {
				memset(&chnStat, 0, sizeof(IMPEncoderCHNStat));
				ret = IMP_Encoder_Query(chn[i].index, &chnStat);
				if (ret < 0) {
					IMP_LOG_ERR(TAG, "IMP_Encoder_Query(%d) failed\n", chn[i].index);
					return -1;
				}

				if (chnStat.registered) {
					ret = IMP_Encoder_UnRegisterChn(chn[i].index);
					if (ret < 0) {
						IMP_LOG_ERR(TAG, "IMP_Encoder_UnRegisterChn(%d) failed\n", chn[i].index);
						return -1;
					}

					ret = IMP_Encoder_DestroyChn(chn[i].index);
					if (ret < 0) {
						IMP_LOG_ERR(TAG, "IMP_Encoder_DestroyChn(%d) failed\n", chn[i].index);
						return -1;
					}
				}
				if (chn[i].index == 0) {
					memset(&chnStat, 0, sizeof(IMPEncoderCHNStat));
					ret = IMP_Encoder_Query(3+chn[i].index, &chnStat);
					if (ret < 0) {
						IMP_LOG_ERR(TAG, "IMP_Encoder_Query(%d) failed\n", 3+chn[i].index);
						return -1;
					}

					if (chnStat.registered) {
						ret = IMP_Encoder_UnRegisterChn(3+chn[i].index);
						if (ret < 0) {
							IMP_LOG_ERR(TAG, "IMP_Encoder_UnRegisterChn(%d) failed\n", 3+chn[i].index);
							return -1;
						}

						ret = IMP_Encoder_DestroyChn(3+chn[i].index);
						if (ret < 0) {
							IMP_LOG_ERR(TAG, "IMP_Encoder_DestroyChn(%d) failed\n", 3+chn[i].index);
							return -1;
						}
					}
				}
			}
		}
		for (i = 0; i < FS_CHN_NUM; i++) {
			if (chn[i].enable) {
				ret = IMP_Encoder_DestroyGroup(chn[i].index);
				if (ret < 0) {
					IMP_LOG_ERR(TAG, "IMP_Encoder_DestroyGroup(%d) failed\n", chn[i].index);
					return -1;
				}
			}
		}
	}

	/* Step.d FrameSource exit */
	{
		for (i = 0; i < FS_CHN_NUM; i++) {
			if (chn[i].enable) {
				ret = IMP_FrameSource_DestroyChn(chn[i].index);
				if (ret < 0) {
					IMP_LOG_ERR(TAG, "IMP_FrameSource_DestroyChn(%d) failed\n", chn[i].index);
					return -1;
				}
			}
		}
	}

	/* Step.e System exit */
	{
		IMP_System_Exit();

		ret = IMP_ISP_DisableSensor();
		if (ret < 0) {
			IMP_LOG_ERR(TAG, "IMP_ISP_DisableSensor failed\n");
			return -1;
		}

		ret = IMP_ISP_DelSensor(&sensor_info);
		if (ret < 0) {
			IMP_LOG_ERR(TAG, "IMP_ISP_DelSensor failed\n");
			return -1;
		}

		ret = IMP_ISP_DisableTuning();
		if (ret < 0) {
			IMP_LOG_ERR(TAG, "IMP_ISP_DisableTuning failed\n");
			return -1;
		}

		ret = IMP_ISP_Close();
		if (ret < 0) {
			IMP_LOG_ERR(TAG, "IMP_ISP_Close failed\n");
			return -1;
		}
	}

	return 0;
}

#ifdef SAVE_STREAM
static int save_stream_test(int fd, IMPEncoderStream *stream)
{
	int i = 0;
	int ret = 0;
	int nr_pack = stream->packCount;

	for (i = 0; i < nr_pack; i++) {
		ret = write(fd, (void *)stream->pack[i].virAddr, stream->pack[i].length);
		if (ret != stream->pack[i].length) {
			close(fd);
			IMP_LOG_ERR(TAG, "stream write failed\n");
			return -1;
		}
	}

	return 0;
}

static int save_stream_by_name_test(char *stream_prefix, int idx, IMPEncoderStream *stream)
{
	int i = 0;
	int ret = 0;
	int stream_fd = -1;
	char stream_path[128] = { 0 };
	int nr_pack = stream->packCount;

	sprintf(stream_path, "%s-%02d.jpg", stream_prefix, idx%3);

	IMP_LOG_DBG(TAG, "Open Stream file %s ", stream_path);
	stream_fd = open(stream_path, O_RDWR | O_CREAT | O_TRUNC, 0777);
	if (stream_fd < 0) {
		IMP_LOG_ERR(TAG, "open %s failed\n", stream_path);
		return -1;
	}
	IMP_LOG_DBG(TAG, "OK\n");

	for (i = 0; i < nr_pack; i++) {
		ret = write(stream_fd, (void *)stream->pack[i].virAddr, stream->pack[i].length);
		if (ret != stream->pack[i].length) {
			close(stream_fd);
			IMP_LOG_ERR(TAG, "stream write failed\n");
			return -1;
		}
	}

	close(stream_fd);

	return 0;
}
#endif

static void *get_video_stream_chn0(void *args)
{
	int i = 0;
	int ret = 0;
	char thread_name[32] = { 0 };
	IMPEncoderStream stream;
#ifdef SAVE_STREAM
	int stream_fd = -1;
	char stream_path[64] = { 0 };
#endif

	int val = (int)args;
	int chnNum = val & 0xffff;
#ifdef SAVE_STREAM
	IMPPayloadType payloadType = (val >> 16) & 0xffff;
#endif
	sprintf(thread_name, "%s-%d", "getstream", chnNum);
	prctl(PR_SET_NAME, (unsigned long)thread_name);

	ret = IMP_Encoder_StartRecvPic(chnNum);
	if (ret < 0) {
		IMP_LOG_ERR(TAG, "IMP_Encoder_StartRecvPic(%d) failed\n", chnNum);
		goto err_StartRecvPic;
	}

#ifdef SAVE_STREAM
	sprintf(stream_path, "%s/stream-encoder-changeRes-%d-%dx%d.%s", STREAM_FILE_PATH_PREFIX, chnNum,
			chn[chnNum].fs_chn_attr.picWidth, chn[chnNum].fs_chn_attr.picHeight,
			(payloadType == PT_H264) ? "h264" : "h265");

	IMP_LOG_DBG(TAG, "Video ChnNum=%d Open Stream file %s ", chnNum, stream_path);
	stream_fd = open(stream_path, O_RDWR | O_CREAT | O_TRUNC, 0777);
	if (stream_fd < 0) {
		IMP_LOG_ERR(TAG, "open %s failed\n", stream_path);
		goto err_open;
	}
	IMP_LOG_DBG(TAG, "OK\n");
#endif

	for (i = 0; i < NR_FRAMES_TO_SAVE; i++) {
		ret = IMP_Encoder_PollingStream(chnNum, 1000);
		if (ret < 0) {
			IMP_LOG_ERR(TAG, "IMP_Encoder_PollingStream(%d) timeout\n", chnNum);
			continue;
		}

		/* Get H264 or H265 Stream */
		ret = IMP_Encoder_GetStream(chnNum, &stream, 1);
		if (ret < 0) {
			IMP_LOG_ERR(TAG, "IMP_Encoder_GetStream(%d) failed\n", chnNum);
			goto err_GetStream;
		}

#ifdef SAVE_STREAM
		ret = save_stream_test(stream_fd, &stream);
		if (ret < 0) {
			goto err_SaveStream;
		}
#endif
		if(i == NR_FRAMES_TO_SAVE * 4 / 5)
			getJpeg[chnNum] = 0;

		IMP_Encoder_ReleaseStream(chnNum, &stream);
	}

#ifdef SAVE_STREAM
	close(stream_fd);
#endif

	ret = IMP_Encoder_StopRecvPic(chnNum);
	if (ret < 0) {
		IMP_LOG_ERR(TAG, "IMP_Encoder_StopRecvPic(%d) failed\n", chnNum);
		goto err_StopRecvPic;
	}

	return NULL;
#ifdef SAVE_STREAM
err_SaveStream:
	IMP_Encoder_ReleaseStream(chnNum, &stream);
#endif
err_GetStream:
#ifdef SAVE_STREAM
	close(stream_fd);
err_open:
#endif
	IMP_Encoder_StopRecvPic(chnNum);
err_StopRecvPic:
err_StartRecvPic:
	return NULL;
}

static void *get_video_stream_chn1(void *args)
{
	int ret = 0;
	char thread_name[32] = { 0 };
	IMPEncoderStream stream;
#ifdef SAVE_STREAM
	int stream_fd = -1;
	char stream_path[64] = { 0 };
#endif

	int val = (int)args;
	int chnNum = val & 0xffff;
#ifdef SAVE_STREAM
	IMPPayloadType payloadType = (val >> 16) & 0xffff;
#endif
	sprintf(thread_name, "%s-%d", "getstream", chnNum);
	prctl(PR_SET_NAME, (unsigned long)thread_name);

	ret = IMP_Encoder_StartRecvPic(chnNum);
	if (ret < 0) {
		IMP_LOG_ERR(TAG, "IMP_Encoder_StartRecvPic(%d) failed\n", chnNum);
		goto err_StartRecvPic;
	}

#ifdef SAVE_STREAM
	sprintf(stream_path, "%s/stream-encoder-changeRes-%d-%dx%d.%s", STREAM_FILE_PATH_PREFIX, chnNum,
			chn[chnNum].fs_chn_attr.picWidth, chn[chnNum].fs_chn_attr.picHeight,
			(payloadType == PT_H264) ? "h264" : "h265");
#endif

	int count = 0;
	while (getVideo[chnNum] == 1) {
#ifdef SAVE_STREAM
		if(count++ % 200 == 0) {  
			IMP_LOG_DBG(TAG, "Video ChnNum=%d Open Stream file %s ", chnNum, stream_path);
			stream_fd = open(stream_path, O_RDWR | O_CREAT | O_TRUNC, 0777);
			if (stream_fd < 0) {
				IMP_LOG_ERR(TAG, "open %s failed\n", stream_path);
				goto err_open;
			}
			IMP_LOG_DBG(TAG, "OK\n");
		}
#endif
		ret = IMP_Encoder_PollingStream(chnNum, 1000);
		if (ret < 0) {
			IMP_LOG_ERR(TAG, "IMP_Encoder_PollingStream(%d) timeout\n", chnNum);
			continue;
		}

		/* Get H264 or H265 Stream */
		ret = IMP_Encoder_GetStream(chnNum, &stream, 1);
		if (ret < 0) {
			IMP_LOG_ERR(TAG, "IMP_Encoder_GetStream(%d) failed\n", chnNum);
			goto err_GetStream;
		}

#ifdef SAVE_STREAM
		ret = save_stream_test(stream_fd, &stream);
		if (ret < 0) {
			goto err_SaveStream;
		}
#endif
		IMP_Encoder_ReleaseStream(chnNum, &stream);

#ifdef SAVE_STREAM
		if(count % 200 == 0){
			close(stream_fd);
		}
#endif
	}

	ret = IMP_Encoder_StopRecvPic(chnNum);
	if (ret < 0) {
		IMP_LOG_ERR(TAG, "IMP_Encoder_StopRecvPic(%d) failed\n", chnNum);
		goto err_StopRecvPic;
	}

	return NULL;
#ifdef SAVE_STREAM
err_SaveStream:
	IMP_Encoder_ReleaseStream(chnNum, &stream);
#endif
err_GetStream:
#ifdef SAVE_STREAM
	close(stream_fd);
err_open:
#endif
	IMP_Encoder_StopRecvPic(chnNum);
err_StopRecvPic:
err_StartRecvPic:
	return NULL;
}

static void *get_jpeg_stream_chn3(void *args)
{
	srand((unsigned int)time(NULL));
	int i = 0;
	int ret = 0;
	IMPEncoderStream stream;
	char thread_name[32] = { 0 };
#ifdef SAVE_STREAM
	char stream_path[64] = { 0 };
#endif

	int val = (int)args;
	int chnNum = val & 0xffff;

#ifdef SAVE_STREAM
	sprintf(stream_path, "%s/stream-encoder-changeRes-%d-%dx%d", STREAM_FILE_PATH_PREFIX, chnNum,
			chn[chnNum-3].fs_chn_attr.picWidth, chn[chnNum-3].fs_chn_attr.picHeight);
#endif
	sprintf(thread_name, "%s-%d", "getstream", chnNum);
	prctl(PR_SET_NAME, (unsigned long)thread_name);

	while (getJpeg[chnNum-3] == 1) {
		ret = IMP_Encoder_StartRecvPic(chnNum);
		if (ret < 0) {
			IMP_LOG_ERR(TAG, "IMP_Encoder_StartRecvPic(%d) failed\n", chnNum);
			goto err_StartRecvPic;
		}

		ret = IMP_Encoder_PollingStream(chnNum, 1000);
		if (ret < 0) {
			IMP_LOG_ERR(TAG, "IMP_Encoder_PollingStream(%d) timeout\n", chnNum);
			continue;
		}

		/* Get JPEG Snap */
		ret = IMP_Encoder_GetStream(chnNum, &stream, 1);
		if (ret < 0) {
			IMP_LOG_ERR(TAG, "IMP_Encoder_GetStream(%d) failed\n", chnNum);
			goto err_GetStream;
		}

#ifdef SAVE_STREAM
		ret = save_stream_by_name_test(stream_path, i, &stream);
		if (ret < 0) {
			IMP_LOG_ERR(TAG, "save_stream_by_name_test failed\n");
			goto err_SaveStream;
		}
#endif

		IMP_Encoder_ReleaseStream(chnNum, &stream);

		ret = IMP_Encoder_StopRecvPic(chnNum);
		if (ret < 0) {
			IMP_LOG_ERR(TAG, "IMP_Encoder_StopRecvPic(%d) failed\n", chnNum);
			goto err_StopRecvPic;
		}
		i++;
		// printf("[%s %d] cnt=%d\n", __func__, __LINE__, i);
		sleep(rand()%10+1);
	}

	return NULL;
#ifdef SAVE_STREAM
err_SaveStream:
	IMP_Encoder_ReleaseStream(chnNum, &stream);
#endif
err_GetStream:
	IMP_Encoder_StopRecvPic(chnNum);
err_StopRecvPic:
err_StartRecvPic:
	return NULL;
}
